package com.itheima.filter;

import com.alibaba.fastjson.JSON;
import com.itheima.common.R;
import com.itheima.common.ReggieConstants;
import com.itheima.common.ReggieContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 检查用户是否已经完成登录
 */
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter{

    private static  final AntPathMatcher ANT_PATH_MATCHER = new AntPathMatcher();

    private static final String [] URI_PATTERN = new String[]{
            "/employee/login",
            "/backend/**",
            "/front/**",
            "/common/upload",
            "/common/download",
            "/user/sendMsg", // 移动端发送短信
            "/user/login" // 移动端登录
    };

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
//        log.info("过滤器过滤到了,uri:{},url:{}", req.getRequestURI(), req.getRequestURL());
        //1、获取本次请求的URI
        String uri = req.getRequestURI();

        // 2 判断本次请求 是否需要登录才可以访问
        // 2.1 先定义一个可以直接访问的uro(不需要登录就能访问的)

        boolean letGo = match(uri);

        // 3 . 如果不需要 则直接放行
        if (letGo){
            chain.doFilter(request,response);
            return;
        }
        // 4-1 . 判断登录状态,如果已登录,则直接放行
        Long empId = (Long) req.getSession().getAttribute(ReggieConstants.EMP_SESSION_KEY);
        if (empId!=null){

            // 已登录
            ReggieContext.set(empId);

            chain.doFilter(request,response);
            // 手动remove一下 防止出现oom
            ReggieContext.remove();
            return;
        }

        // 4-1 . 判断登录状态,如果已登录,则直接放行
        Long userId = (Long) req.getSession().getAttribute(ReggieConstants.USER_SESSION_KEY);
        if (userId!=null){

            // 已登录
            ReggieContext.set(userId);

            chain.doFilter(request,response);
            // 手动remove一下 防止出现oom
            ReggieContext.remove();
            return;
        }

        // 5 如果未登录,则返回未登录结果
        // 因为现在是再servlet中, 直接write是不会帮我们转json的 需要自己转
        resp.getWriter().write(JSON.toJSONString(R.error(ReggieConstants.NOT_LOGIN_KEY)));
    }

    private boolean match(String uri){
        for (String pattern : URI_PATTERN){
            boolean result = ANT_PATH_MATCHER.match(pattern, uri);
            //匹配上了我的可放行资源,就直接返回了
            if (result){
                return true;
            }
        }
        // 还没有return,说明没匹配上
        return  false;
    }

}
